package py.com.alfa.escriba.exception;

import java.util.Locale;

import javax.ws.rs.ext.Provider;

import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import py.com.alfa.escriba.config.EscribaApplicationContextProvider;
import py.com.alfa.escriba.util.JSONTranslator;




@Provider
public class ServiceException extends RuntimeException {
	private static final long serialVersionUID = -1417575380801996290L;
	private ErrorCode errorCode;
	@SuppressWarnings("unused")
	private Logger log = LoggerFactory.getLogger(getClass());
	private static final String DEFAULT_MESSAGE = "NO SE ENCUENTRA LA DESCRIPCION DEL ERROR";
  
	public ServiceException(ErrorCode errorCode) {
		super();
		this.errorCode = errorCode;
	}
	
	public ServiceException(ErrorCode errorCode, String message, Throwable cause) {
		super(EscribaApplicationContextProvider.getContext()
        .getMessage(message, null , DEFAULT_MESSAGE, Locale.getDefault()).toUpperCase(), cause);
		this.errorCode = errorCode;
	}
	
	public ServiceException(ErrorCode errorCode, String message) {
		super(EscribaApplicationContextProvider.getContext()
        .getMessage(message, null , DEFAULT_MESSAGE, Locale.getDefault()).toUpperCase());
		this.errorCode = errorCode;
	}
	
	public ServiceException(ErrorCode errorCode, Throwable cause) {
		super(cause);
		this.errorCode = errorCode;
	}

	public ErrorCode getErrorCode(){
		return this.errorCode;
	}
	
	public String getErrorMessage(){
		StringBuilder sb = new StringBuilder();
		sb.append(getErrorCode()).append("=").append(this.getMessage()).append("\n");
		return sb.toString();
	}
	
	public ServiceException(ErrorCode errorCode, Throwable cause, String message, Object...args) {
		super(EscribaApplicationContextProvider.getContext()
        .getMessage(message, args , DEFAULT_MESSAGE, Locale.getDefault()).toUpperCase(), cause);
		this.errorCode = errorCode;
	}
	
	public ServiceException(ErrorCode errorCode, String message, Object...args) {
		super(EscribaApplicationContextProvider.getContext()
        .getMessage(message, args , DEFAULT_MESSAGE, Locale.getDefault()).toUpperCase());
		this.errorCode = errorCode;
	}

		
	public String toJSON(){
		JSONError jse = new JSONError();
		jse.setCauseString(this.getCause() == null ? "" : this.getCause().toString());
		jse.setErrorKey(this.errorCode.toString());
		jse.setErrorMessage(this.getMessage() == null ? "" : this.getMessage());
		
		JSONTranslator<JSONError> t = new JSONTranslator<ServiceException.JSONError>(ServiceException.JSONError.class);
		
		try {
			return t.toJSON(jse);
		} catch (ServiceException e) {
			throw new RuntimeException("FATAL: cannot convert ServiceException into JSONError from within a ServiceException",e);
		}
	}	

	
	@JsonSerialize(include=Inclusion.NON_EMPTY)
	static final class JSONError {
		private String errorKey;
		private String errorMessage;		
		private String causeString;
		private String messages[];
		
		public String getErrorKey() {
			return errorKey;
		}
		public void setErrorKey(String errorKey) {
			this.errorKey = errorKey;
		}
		public String getErrorMessage() {
			return errorMessage;
		}
		public void setErrorMessage(String errorMessage) {
			this.errorMessage = errorMessage;
		}
		public String getCauseString() {
			return causeString;
		}
		public void setCauseString(String causeString) {
			this.causeString = causeString;
		}
		public String[] getMessages() {
			return messages;
		}
		public void setMessages(String[] messages) {
			this.messages = messages;
		}		
	}
}